/*
 * @Author: fengzhilun 1902098845@qq.com
 * @Date: 2024-03-04 11:49:33
 * @LastEditors: fengzhilun 1902098845@qq.com
 * @LastEditTime: 2024-08-28 15:58:54
 * @FilePath: \myVite\src\utils\tsType.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/**   */
type pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

type Request<T> = {
  [P in keyof T]-?: T[P];
};
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};
type Record<K extends string | number | symbol, T> = {
  [P in K]: T;
};
// 取集合的并集的反
type Exclude<T, U> = T extends U ? never : T;

/** 取并集 */
type Extract<T, U> = T extends U ? T : never;

const c: Exclude<"name" | "value" | "type", "name" | "val"> = "value";

type OMit<T, U extends keyof T> = pick<T, Exclude<keyof T, U>>;

const vals = { name: "123", value: "123" };
const vals2 = () => {};

const d: keyof typeof vals = "name";
const dd: typeof vals2 = () => {};

/**用数组存储比较好。 */
type Parame<T> = T extends (...params: infer U) => any ? U : never;

const aa: Parame<(params: { name?: string }) => void> = [{ name: "" }];

type Return<T extends (...params: any[]) => any> = T extends (
  param: any[]
) => infer U
  ? U
  : any;

const bb: Return<() => number> = 12123;

const a: pick<{ name: string; value: number }, "name"> = { name: "str" };

type NonNUllUndefine<T> = T extends undefined | null ? never : T;

type Test = NonNUllUndefine<null | string | undefined>;

/** typeof 获取一个变量或者对象的类型。将js 对象转化成Ts */
type A = keyof typeof a;
const b: A = "name";

//  any 类型可以赋值给任何类型，如果将any 下number 类型赋值给string ,再调用string的方法就会报错 ，引起污染问题
const aaa: any = 123;

const DddD: string = aaa;

// DddD.slice(1,) // 内容报错

// 任何类型都可以赋值给 unknown 类型
const aab: unknown = 12313;
const aac: unknown = "123";

// const DDDb:string = aab  校验不通过
const aad: unknown = { name: "zs" };
// aad.name  // 报错

// 缩小类型
if (typeof aad === "object") {
  console.log((aad as { name: string })?.name, "name");
}
/**
 let v2:unknown = 'hello';
v2.trim() // 报错
let v3:unknown = (n = 0) => n + 1;
v3() // 报错
 */
// 泛型如果在使用时没有具体化的类型,那么就会默认为unknown数据类型
// never 类型为空类型。参数变量x可能是字符串，也可能是数值，判断了这两种情况后，剩下的最后那个else分支里面，x就是never类型了。 任何类型都包括空类型
// 顶层类型 any unknown 底层类型 never

function name(params: string | number): never {
  if (typeof params == "string") {
    ("str");
  } else if (typeof params === "number") {
    123;
  } else {
  }
  throw new Error("error");
}

// declare 关键字
// 声明某种类型是存在的.

// 类型映射 映射（mapping）指的是，将一种类型按照映射规则，转换成另一种类型，通常用于对象类型

type Eee = { name: string; age: number; phone: string };

type Person = {
  [Prop in keyof Eee]: Eee[Prop];
};

type Person1 = {
  [key in "name"]: string;
};

type Myjob = {
  [key in keyof string]: string;
};

// 等价于
type Myjob2 = {
  [key: string]: string;
};

type GetProps<T> = {
  [key in keyof T as `get${Capitalize<string & key>}`]: () => T[key];
};

type getPersonMethod = GetProps<Eee>;

// 过滤 去掉某些属性.
type PersonFilter<T> = {
  [key in keyof T as T[key] extends string ? key : never]: T[key];
};

type FilterPersonData = PersonFilter<Eee>;

// 联合类型映射

type N = {
  kind: "square";
  width: number;
  height: number;
};

type S = {
  kind: "circle";
  radius: number;
};

type ex<T, U> = T extends U ? never : T;

type InC<T, U> = T extends U ? T : never;

type Om<T, U extends string | number | symbol> = {
  [P in ex<keyof T, U>]: T[P];
};

type Pi<T, U extends keyof T> = {
  [P in InC<keyof T, U>]: T[P];
};

type ad = Om<Person, "aaa">;
type ads = Pi<Person, "age">;

/** 测试 */
// type 和interface 的区别。

type a = number;
const bab: a = 123;

// type car = { name: string };
interface car {
  name: string;
}
// type plan = { age: number };
interface plan {
  age: number;
}

type ddd = car | plan;
type FFF = car & plan;

// 接口会将信息合并
interface car {
  price: number;
}

const PPc: car = {
  name: "xxx",
  price: 123,
};

interface CC {
  (): void;
}
const fn123: CC = () => {};

// keyof typeof in infer extends
type MReturn<T> = T extends () => infer U ? U : never;

type MMM = MReturn<() => number>;

export {};

type myExclude<T, U> = T extends U ? never : T;

type myExcludeData = myExclude<keyof car, "age">;

type myInclude<T, U> = T extends U ? T : never;

type myOmit<U, T extends keyof U> = {
  [P in myExclude<keyof U, T>]: U[P];
};

type myPartial<T> = {
  [p in keyof T]?: T[p];
};

type myPartialData = myPartial<car>;

type myPick<T, U extends keyof T> = {
  [p in U]: T[p];
};

type myPickData = myPick<car, "name">;

interface EmployeeType {
  id: number;
  fullname: string;
  role: string;
}

type myRecord<T extends string | number | symbol, U> = {
  [p in T]: U;
};

type myRecordData = myRecord<"false", string>;

type mytest = myOmit<car, "name">;

type myReturnType<T> = T extends (param: any) => infer U ? U : never;
